package com.study.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.study.configs.RedisKeys;
import com.study.dao.NewsMapper;
import com.study.dao.UserMapper;
import com.study.pojo.entity.Newsinfo;
import com.study.pojo.resp.ResultMessage;
import com.study.service.NewsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 首页新闻咨询服务接口实现类
 * @author Screncea
 */
@Service
public class NewsServiceImpl extends ServiceImpl<NewsMapper ,Newsinfo > implements NewsService   {
    @Autowired
    NewsMapper newsMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    UserMapper userMapper;
    /**
     * 首页新闻咨询,根据类型id查询新闻
     * @param typeId 类型id
     * @return 新闻结果集
     */
    @Override
    public ResultMessage findNewsByType(Integer typeId) {
        //判断redis中是否有该字段
        Boolean aBoolean = redisTemplate.hasKey(RedisKeys.NEWS_INFO+typeId);
        if (!aBoolean){
            //从数据库查新闻信息
            List<Newsinfo> newsInfo = newsMapper.selectNewsByType(typeId);
            //判空
            if (newsInfo!=null){
                for (Newsinfo n:newsInfo
                     ) {
                    //存入redis中
                    redisTemplate.opsForHash().put(RedisKeys.NEWS_INFO+typeId,n.getNewsId().toString(),n);
                }

            }else {
                // TODO 如果为空,防止内穿透
                redisTemplate.opsForHash().put(RedisKeys.NEWS_INFO,typeId,"");
                //设置失效时间
                redisTemplate.expire(RedisKeys.NEWS_INFO,60, TimeUnit.SECONDS);
            }
        }
        //类型id获取对应内容
        Map entries = redisTemplate.opsForHash().entries(RedisKeys.NEWS_INFO + typeId.toString());
        System.out.println(entries);
        //判空
        if (StringUtils.isEmpty(entries.toString())){
            return new ResultMessage().ERROR();
        }else {
            return  new ResultMessage(1,"success",entries,null);
        }
    }

    /**
     * 根据新闻在redis中查询新闻内容
     * @param newsId 新闻id
     * @param typeId 新闻类型id
     * @return 新闻结果集
     */
    @Override
    public ResultMessage findNewsByNewsId(Integer typeId,Integer newsId) {
        // TODO 从redis中根据新闻类型id和新闻id查询新闻内容
        Object o = redisTemplate.opsForHash().get(RedisKeys.NEWS_INFO + typeId.toString(), newsId.toString());

        //判空
        if (StringUtils.isEmpty(o.toString())){
            return new ResultMessage().ERROR();
        }else {
            return new ResultMessage(1,"success",o,null);
        }
    }

    /**
     * 用户阅读文章加积分功能
     * @param userId 用户id
     * @param newsId 新闻id
     * @return 结果集
     */
    @Override
    public ResultMessage addIntegral(String newsId,String userId) {
        //首先查看redis中是否存在该用户对应的文章id
        Boolean member = redisTemplate.opsForSet().isMember(RedisKeys.USER_INTEGRAL + userId, newsId);
        if (!member){
            // TODO 如果redis中没有该数据的话,该用户积分+1,并且将新闻id记录在redis中
            userMapper.addIntegral( userId);
            //将新闻id存入redis中
            redisTemplate.opsForSet().add(RedisKeys.USER_INTEGRAL+userId,newsId);
            return new ResultMessage().SUCCESS();
        }
        //如果redis中有该数据,代表用户已经阅读过此篇文章并且加过积分,就不重新添加积分!
        return new ResultMessage().ERROR();
    }

    /**
     * 查找全部新闻信息
     * @return 新闻集合
     */
    @Override
    public ResultMessage findAllNews() {
        //判断redis中是否有该字段
        Boolean aBoolean = redisTemplate.hasKey(RedisKeys.NEWS_INFO);
        if (!aBoolean){
            //从数据库查新闻信息
            List<Newsinfo> newsInfo = newsMapper.findAllNews();
            //判空
            if (newsInfo!=null){
                for (Newsinfo n:newsInfo
                ) {
                    //存入redis中
                    redisTemplate.opsForHash().put(RedisKeys.NEWS_INFO,n.getNewsId().toString(),n);
                }

            }else {
                // TODO 如果为空,防止内穿透
                redisTemplate.opsForHash().put(RedisKeys.NEWS_INFO,0,"");
                //设置失效时间
                redisTemplate.expire(RedisKeys.NEWS_INFO,60, TimeUnit.SECONDS);
            }
        }
        //类型id获取对应内容
        Map entries = redisTemplate.opsForHash().entries(RedisKeys.NEWS_INFO);
        System.out.println(entries);
        //判空
        if (StringUtils.isEmpty(entries.toString())){
            return new ResultMessage().ERROR();
        }else {
            return  new ResultMessage(1,"success",entries,null);
        }
    }

    /**
     * 根据新闻在redis中查询新闻内容
     * @param newsId 新闻id
     * @return 新闻结果集
     */
    @Override
    public ResultMessage findNewsById(String newsId) {
        // TODO 从redis中根据新闻类型id和新闻id查询新闻内容
        Object o = redisTemplate.opsForHash().get(RedisKeys.NEWS_INFO , newsId.toString());

        //判空
        if (StringUtils.isEmpty(o.toString())){
            return new ResultMessage().ERROR();
        }else {
            return new ResultMessage(1,"success",o,null);
        }
    }
}
